#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>

typedef long long ll;
const int N = 3005;
int n, m, deg[N];
ll dis[N], tim[N], arr[N];

std::priority_queue<std::pair<ll, int>, std::vector<std::pair<ll, int> >,
                    std::greater<std::pair<ll, int> > >
    pq;

struct Graph {
  struct Edge {
    int v, nxt, w;
  } e[140005];
  int e_cnt, heads[N];
  inline void add(const int &u, const int &v, const int &w) {
    e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt, e[e_cnt].w = w;
  }
} E, G;

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("testdata.in", "r", stdin);
  freopen("testdata.out", "w", stdout);
#else
  freopen("P2446 [SDOI2010]大陆争霸.in", "r", stdin);
  freopen("P2446 [SDOI2010]大陆争霸.out", "w", stdout);
#endif
#endif

  scanf("%d%d", &n, &m);
  for (int i = 1, u, v, w; i <= m; ++i) {
    scanf("%d%d%d", &u, &v, &w);
    E.add(u, v, w);
  }
  for (int i = 1, l, v; i <= n; ++i) {
    scanf("%d", &l);
    for (int j = 1; j <= l; ++j) {
      scanf("%d", &v);
      G.add(v, i, 0);
      deg[i]++;
    }
  }
  memset(dis, 0x3f, sizeof(dis));
  memset(arr, 0x3f, sizeof(arr));
  dis[1] = tim[1] = arr[1] = 0;
  pq.emplace(0, 1);
  while (!pq.empty()) {
    int u = pq.top().second, d = pq.top().first;
    pq.pop();
    if (d != dis[u]) continue;
    for (int i = E.heads[u], v; i; i = E.e[i].nxt) {
      if (arr[v = E.e[i].v] > dis[u] + E.e[i].w) {
        arr[v] = dis[u] + E.e[i].w;
        if (!deg[v]) {
          dis[v] = std::max(tim[v], arr[v]);
          pq.emplace(dis[v], v);
        }
      }
    }
    for (int i = G.heads[u], v; i; i = G.e[i].nxt) {
      v = G.e[i].v;
      tim[v] = std::max(tim[v], dis[u]);
      if (!--deg[v]) {
        dis[v] = std::max(tim[v], arr[v]);
        pq.emplace(dis[v], v);
      }
    }
  }
  printf("%lld", dis[n]);
  return 0;
}
